#ifndef _USERS_H_
#define _USERS_H_


#include "Common.h"
#include "Resource.h"
#include "String.h"
#include "SharedPtr.h"
#include "ResourceManager.h"

enum  UserLoadStatus
{
	USER_LOAD_STATUS_NONE = 0,
	USER_LOAD_STATUS_SUCCEED,
	USER_LOAD_STATUS_ERROR
};

enum  UserLoginStatus
{
	USER_LOGIN_STATUS_NONE = 0,
	USER_LOGIN_STATUS_LOGING = 1,   // user login in game server
	USER_LOGIN_STATUS_PREBS = 2,   // user pre want login to battle server
	USER_LOGIN_STATUS_BS = 3,	// user login to battle server succeed;
	USER_LOGIN_STATUS_OUTBS = 4,	// user loginout  battle server;
	USER_LOGIN_STATUS_ERROR = 5     // user login has error
};

class SERVER_DECL User : public Resource
{
protected:
	uint32		m_serial;
	uint32		m_group_id;    //login server group id
	String		m_UserName;
	String		m_Session;
	String		m_Nick;
	UserLoadStatus	m_loadStatus;
	UserLoginStatus	m_Status;

	//uint32		m_client_id;

        void prepareImpl(void);
        /** Destroys data cached by prepareImpl.
         */
        void unprepareImpl(void);
        /// @copydoc Resource::loadImpl
        bool loadImpl(void);
        /// @copydoc Resource::postLoadImpl
        void postLoadImpl(void);
        /// @copydoc Resource::unloadImpl
        void unloadImpl(void);
        /// @copydoc Resource::calculateSize
        size_t calculateSize(void) const;

	void initialize(void);

public:
	User(ResourceManager* creator, const String& name, ResourceHandle handle,
            const String& group, bool isManual = false, ManualResourceLoader* loader = 0);
	~User(void);


	const uint32 & getSerial(void)		{	return m_serial;	}

	const uint32 & getGid(void)		{	return m_group_id;	}
	
	const String &  getUserName(void)	{	return m_UserName;	}
	

	const String & getNick(void)		{	return m_Nick;	}
	void 	setNick(const String & nick)	{	m_Nick = nick;	}

        //const uint32 & getClientID(void)        {       return m_client_id;     }
        //void    setClientID(const uint32 & sockid)              {       m_client_id = sockid;   }	

	const String & getSession(void)		{	return m_Session;	}
	

	const UserLoadStatus & getLoadStatus(void)	{	return m_loadStatus;	}
	void	setLoadStatus(const UserLoadStatus & status)	{	m_loadStatus = status;	}

	const UserLoginStatus & getLoginStatus(void)	{	return m_Status;	}
	void	setLoginStatus(const UserLoginStatus & status);
	

	bool	SaveDB(void);
	bool	LoadDB(void);
	bool    FetchDB(Field * fields);

	//用户的Socket
	ResourceProxy 	m_Socket;

	/* base server_id and username connect db get uid
	 if resource loaded direct return uid */

private:
	/* base server_id and username connect db get uid
	 if resource loaded direct return uid */
};

    /** Specialisation of SharedPtr to allow SharedPtr to be assigned to UserPtr 
    @note Has to be a subclass since we need operator=.
    We could templatise this instead of repeating per Resource subclass, 
    except to do so requires a form VC6 does not support i.e.
    ResourceSubclassPtr<T> : public SharedPtr<T>
    */
    class SERVER_DECL  UserPtr : public SharedPtr<User>
    {
    public:
        UserPtr() : SharedPtr<User>() {}
        explicit UserPtr(User* rep) : SharedPtr<User>(rep) {}
        UserPtr(const UserPtr& r) : SharedPtr<User>(r) {}
        UserPtr(const ResourcePtr& r);
        /// Operator used to convert a ResourcePtr to a MeshPtr
        UserPtr& operator=(const ResourcePtr& r);
    protected:
        /// Override destroy since we need to delete Mesh after fully defined
        void destroy(void);
    };
	

#endif
